package com.zysstudy.stream;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamStudy {

    public static void main(String[] args) {
        StreamStudy streamStudy = new StreamStudy();
//        streamStudy.demo1();
//        streamStudy.demo2();
//        streamStudy.demo3();
//        streamStudy.demo4();
//        streamStudy.demo5();
        //
        List<dataEntity> list = getData();
        list.forEach(s->System.out.println(s));
    }


    private static List<dataEntity> getData() {

        dataEntity entity1 =  new dataEntity();
        entity1.setId(Long.parseLong("1"));
        entity1.setName("test1");
        entity1.setType(1);
        entity1.setChang("1");
        dataEntity entity2 = new dataEntity();
        entity2.setId(Long.parseLong("2"));
        entity2.setName("test2");
        entity2.setType(2);
        entity2.setChang("2");

        dataEntity entity3 = new dataEntity();
        entity3.setId(Long.parseLong("3"));
        entity3.setName("test3");
        entity3.setType(3);
        entity3.setChang("3");

        dataEntity entity4 = new dataEntity();
        entity4.setId(Long.parseLong("4"));
        entity4.setName("test4");
        entity4.setType(4);
        entity4.setChang("4");
        List<dataEntity> list = new ArrayList<>();
        list.add(entity1);
        list.add(entity2);
        list.add(entity3);
        list.add(entity4);
        return list;
    }

    public void demo1() {
        // 在Java中，Stream流一旦被终端操作（如collect、forEach）使用过，就不能再次使用
        //Function.identity()的使用详解
        // stream.collect(Collectors.toMap(key,value);
        Stream<String> stream = Stream.of("This", "is", "a", "test");

        Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));

        //流的遍历forEach 这个会报错【语法错误】
//        stream.forEach(s -> System.out.println(s + "长度是:" + map.get(s)));


        List<String> list = Arrays.asList("This", "is", "a", "test");

        Map<String, Integer> map2 = list.stream().collect(Collectors.toMap(Function.identity(), String::length));

        //流的遍历forEach
        list.forEach(s -> System.out.println(s + "长度是:" + map2.get(s)));
    }

    /**
     * stream filter forEach
     */
    private void demo2() {
        List<String> list = new ArrayList<>();

        list.add("左宥");
        list.add("尚夏");
        list.add("钱後");
        list.add("钱理群");

        List<String> qianList = new ArrayList<>();
        for (String s : list) {
            if (s.startsWith("钱")) {
                qianList.add(s);
            }
        }

        List<String> shortList = new ArrayList<>();

        for (String s : qianList) {
            if (s.length() < 3) {
                shortList.add(s);
            }
        }

        for (String s : shortList) {
            System.out.println("list:" + s);
        }


        // stream的写法
        // 很显然，简单明了多了
        list.stream()
                .filter(s -> s.startsWith("钱"))
                .filter(s -> s.length() < 3)
                .forEach(s -> System.out.println("stream:" + s));

    }


    private void demo3() {
        String[] array = {"页文洁", "罗技", "水滴"};
        List<String> list = Arrays.asList("This", "is", "a", "test");
        Stream<String> streamString = Arrays.stream(array).limit(2);
        streamString.forEach(System.out::println);

        //Stream.of 是快速创建流的便捷方法，适合处理少量已知元素。
        Stream.of("A", null, "C").forEach(System.out::println); // 输出：A → null → C


        //处理对象数组
        Integer[] integerArray = {10, 20, 30};
        System.out.println(Arrays.stream(integerArray).count());
        Stream<Integer> integerStream = Arrays.stream(integerArray);
        //mapToInt(i->i::intValue)
        System.out.println("Sum: " + integerStream.mapToInt(i -> i).sum());

        //

        List tlist = Arrays.asList("11", "22");
        List<String> tlist2 = new ArrayList<>();
        tlist2.add("12");


    }

    /**
     * limit
     * findFirst
     * sum
     * max
     * min
     * reduce 可以将流中元素反复结合起来，得到一个值
     * anyMatch 检查是否匹配所有元素，返回boolean
     * noneMatch  检查是否没有匹配所有元素，返回boolean
     */
    private void demo4() {
        // limit 返回是个Stream
        List<dataEntity> data = getData();
        Stream<dataEntity> tmpdata = data.stream().limit(2);
        List<dataEntity> t = tmpdata.collect(Collectors.toList());
        System.out.println(t);

        // findFirst
        Map<String, Object> result = data.stream().findFirst().map(b -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id11", b.getId());
            map.put("name11", b.getName());
            System.out.println("我是B" + b.toString());
            return map;
        }).orElse(Collections.emptyMap()); // 流为空时返回空 Map
        System.out.println(result);

        //sum
        Integer result1 = data.stream().mapToInt(s -> Integer.parseInt(s.getChang())).sum();
        System.out.println("sum结果：" + result1);

        //max
        dataEntity result2 = data.stream().max(Comparator.comparingInt(s -> s.getType())).get();
        System.out.println("Type最大值：" + result2);

        // min
        dataEntity result3 = data.stream().min(Comparator.comparingInt(s -> Integer.parseInt(s.getChang()))).get();
        System.out.println("chang最小值：" + result3);
    }

    /**
     * collect
     * 收集器，将流转换为其他形式
     * <p>
     * Collect收集
     * Collector：结果收集策略的核心接口，具备将指定元素累加存放到结果容器中的能力；并在Collectors工具中提供了Collector接口的实现类
     * toList方法 将用户ID存放到List集合中
     * toMap 方法 将用户ID和Name以Key-Value形式存放到Map集合中
     * toSet 方法 将用户所在城市存放到Set集合中
     * counting  符合条件的用户总数
     * summingInt
     * minBy
     * joining
     * groupingBy
     */
    private void demo5() {
        List<dataEntity> data = getData();

        // 按 type 分组，统计每组 chang 总和
        Map<Integer, Integer> res1 = data.stream()
                .collect(Collectors.groupingBy(
                        dataEntity::getType,
                        Collectors.summingInt(entity -> Integer.parseInt(entity.getChang()))
                ));
        System.out.println("按 type 分组，统计每组 chang 总和:"+res1);

        //tomap
        Map<String,dataEntity> res2= data.stream().collect(Collectors.toMap(dataEntity::getChang,dataEntity -> dataEntity));
        System.out.println(res2);

        Map<String,dataEntity> res3= data.stream().collect(Collectors.toMap(dataEntity::getChang,Function.identity()));
        System.out.println(res3);

        Map<String,Integer> res4= data.stream().collect(Collectors.toMap(dataEntity::getChang,dataEntity::getType));
        System.out.println(res4);


        //tolist
        List<Integer> res5 = data.stream().map(dataEntity -> dataEntity.getType()).collect(Collectors.toList());
        System.out.println("tolist"+res5);

        List<Integer> res6 = data.stream().filter(s->s.getType()==1)
                .map(dataEntity::getType).collect(Collectors.toList());
        System.out.println("tolist+filter:"+res6);


    }


}
